package com.axend.aerosense.room.ui.fragment;

import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import com.axend.aerosense.base.bean.BaseBean;
import com.axend.aerosense.base.fragment.MvvmBaseFragment;
import com.axend.aerosense.base.impl.ILoadDataResult;
import com.axend.aerosense.base.impl.ILoginStatusChanged;
import com.axend.aerosense.base.viewmodel.BaseViewModelFactroy;
import com.axend.aerosense.common.bean.FunctionRoomEnum;
import com.axend.aerosense.common.bean.VipSettingTime;
import com.axend.aerosense.common.ui.BottomTextPickerDialog;
import com.axend.aerosense.common.ui.CustomTitleTipsDialog;
import com.axend.aerosense.room.BR;
import com.axend.aerosense.room.R;
import com.axend.aerosense.room.databinding.RoomFragmentSettingFunctionBinding;
import com.axend.aerosense.room.entity.RoomRemindBean;
import com.axend.aerosense.room.entity.RoomVipSetBean;
import com.axend.aerosense.room.entity.VipFunSaveDataBean;
import com.axend.aerosense.room.listener.OnBackCallback;
import com.axend.aerosense.room.ui.activity.RoomSettingFunctionActivity;
import com.axend.aerosense.room.viewmodel.RoomSettingFunctionViewModel;
import com.blankj.utilcode.util.LogUtils;
import com.jzxiang.pickerview.data.Type;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 房间设置功能界面
 */
public class RoomSettingFunctionFragment
        extends MvvmBaseFragment<RoomFragmentSettingFunctionBinding, RoomSettingFunctionViewModel>
        implements ILoginStatusChanged, ILoadDataResult<BaseBean>, OnBackCallback {

    public final static String KEY_FUNCTION_ENUM = "KEY_FUNCTION_ENUM";
    public final static String KEY_VIP_SET_BEAN = "KEY_VIP_SET_BEAN";
    public final static String KEY_ACCUMULATIVE_SETTING = "KEY_ACCUMULATIVE_SETTING";   //累计久坐

    private final static int FLAG_ALERT = 1;
    private final static int FLAG_NOTIFICATION = 2;

    private FunctionRoomEnum functionRoomEnum;
    private RoomVipSetBean roomVipSetBean;  //服务器数据
    private RoomVipSetBean accumulativeSetBean;     //服务器数据（累计久坐）

    private BottomTextPickerDialog pickerDialog;
    private Map<String, Integer> alertTimeMap = new LinkedHashMap<>();
    private Map<String, Integer> notificationTimeMap = new LinkedHashMap<>();

    private int selectAlert;
    private int selectNotification;

    private boolean isBack = false;

    //报警设置
    private VipSettingTime alertSetting;
    //提醒设置
    private VipSettingTime notificationSetting;
    private CustomTitleTipsDialog errorDialog;

    public static RoomSettingFunctionFragment getInstance(Bundle bundle){
        RoomSettingFunctionFragment instance = new RoomSettingFunctionFragment();
        if (null != bundle) {
            instance.setArguments(bundle);
        }
        return instance;
    }

    @Override
    public int getLayoutId() {
        return R.layout.room_fragment_setting_function;
    }

    @Override
    public int getBindingVariable() {
        return BR.model;
    }

    @Override
    protected RoomSettingFunctionViewModel getViewModel() {
        BaseViewModelFactroy<BaseBean> factory =
                new BaseViewModelFactroy<>(this, this);
        RoomSettingFunctionViewModel viewModel =
                new ViewModelProvider(this, factory).get(RoomSettingFunctionViewModel.class);

        return viewModel;
    }

    @Override
    protected void onRetryBtnClick() {

    }

    @Override
    protected void initParameters() {
        Bundle arguments = getArguments();
        if (null == arguments) {
            return;
        }
        functionRoomEnum = (FunctionRoomEnum) arguments.getSerializable(KEY_FUNCTION_ENUM);
        LogUtils.d(functionRoomEnum);
        if (null == functionRoomEnum) {
            LogUtils.d("FunctionRoomEnum is Null");
        }
        //如果是久坐分析，在这里则是连续久坐
        roomVipSetBean = (RoomVipSetBean) arguments.getSerializable(KEY_VIP_SET_BEAN);
        LogUtils.d(roomVipSetBean);
        if (null == roomVipSetBean) {
            LogUtils.d("RoomVipSetBean is Null");
        }

        //久坐分析的累计久坐
        accumulativeSetBean = (RoomVipSetBean) arguments.getSerializable(KEY_ACCUMULATIVE_SETTING);
        LogUtils.d(accumulativeSetBean);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initTimeMap();
        initView();
        setServerValue();
    }

    private void initView() {
        //设置当前页面的设置类型
        viewModel.settingType.setValue(functionRoomEnum.getSettingType());

        //报警设置
        viewDataBinding.roomClAlert.setOnClickListener(v -> {
            //数组下标索引
            int defaultIndex = getDefaultValueIndex(alertSetting);
            showAlertPickerDialog(alertTimeMap, viewDataBinding.roomTvAlertValue, FLAG_ALERT, defaultIndex);
        });
        //通知设置
        viewDataBinding.roomClNotification.setOnClickListener(v -> {
            //数组下标索引
            int defaultIndex = getDefaultValueIndex(notificationSetting);
            showAlertPickerDialog(notificationTimeMap, viewDataBinding.roomTvNotificationValue, FLAG_NOTIFICATION, defaultIndex);
        });
        //第一个提示文字
        int firstTips = functionRoomEnum.getFirstTipsRes();
        if (firstTips != 0) {
            viewDataBinding.roomFunctionTip.setText(firstTips);
        }
        //第二个提示文案
        int secondTips = functionRoomEnum.getSecondTipsRes();
        if (secondTips != 0) {
            viewDataBinding.roomFunctionTip2.setText(secondTips);
        }

        viewDataBinding.roomTvAlertText.setText(
                functionRoomEnum.getSettingType() == 4 ?
                        R.string.room_remind_settings : R.string.room_alarm_settings);

        if (functionRoomEnum == FunctionRoomEnum.SEDENTARY_NOTIFICATION) {
            viewDataBinding.roomFunctionSwitch.setLeftText(getString(R.string.room_sedentary_switch_text));
            viewDataBinding.roomFunctionSwitch2.setLeftText(getString(R.string.room_add_sedentary_switch_text));
        }
    }

    /** 设置服务器上的值 */
    private void setServerValue(){
        int settingType = functionRoomEnum.getSettingType();
        viewModel.functionSwitch.setValue(roomVipSetBean.getFunctionSwitch() == 1);
        //alert
        if (settingType == 1 || settingType == 3 || settingType == 4) {
            int functionAlert = roomVipSetBean.getFunctionAlert();
            if (settingType == 4) {
                //累计久坐
                functionAlert = roomVipSetBean.getFunctionRemind();
            }
            String str = "";
            if (functionAlert <= 0 && alertSetting.getUnitType() != 2) {
                //服务器的设置值为0，则显示默认值
                String key = alertTimeMap.keySet().toArray(new String[alertTimeMap.size()])[getDefaultValueIndex(alertSetting)];
                str = key;
                selectAlert = alertTimeMap.get(key);
            } else {
                str += getSettingValue(alertSetting.getUnitType(), functionAlert, alertTimeMap);
                selectAlert = functionAlert;
            }
            viewDataBinding.roomTvAlertValue.setText(str);
        }

        //notification
        if (settingType == 2 || settingType == 3 || settingType == 4) {
            RoomVipSetBean currentSetBean = roomVipSetBean;
            String str = "";
            if (settingType == 4) {
                //累计久坐
                currentSetBean = accumulativeSetBean;
                viewModel.functionSwitch2.setValue(accumulativeSetBean.getFunctionSwitch() == 1);
            }

            int functionRemind = currentSetBean.getFunctionRemind();
            if (functionRemind <= 0 && notificationSetting.getUnitType() != 2) {
                //服务器的设置值为0，则显示默认值
                String key = alertTimeMap.keySet().toArray(new String[notificationTimeMap.size()])[getDefaultValueIndex(notificationSetting)];
                str = key;
                selectNotification = alertTimeMap.get(key);
            } else {
                str += getSettingValue(notificationSetting.getUnitType(), functionRemind, notificationTimeMap);
                selectNotification = functionRemind;
            }
            viewDataBinding.roomTvNotificationValue.setText(str);
        }
    }


    /** 返回false不返回 */
    @Override
    public boolean onBack() {
//        boolean b = checkAlertAndNotifyData();
//        if (!b) {
//            return false;
//        }

        if (!isBack) {
            isBack = true;
            return saveSettings();
        }
        return true;
    }

    private boolean saveSettings(){
        if (functionRoomEnum != FunctionRoomEnum.SEDENTARY_NOTIFICATION) {
            VipFunSaveDataBean saveDataBean = new VipFunSaveDataBean(
                    roomVipSetBean.getRoomUuid(),
                    roomVipSetBean.getRoomType(),
                    viewModel.functionSwitch.getValue() ? 1 : 0,
                    selectNotification,
                    selectAlert
            );
            if (isChangeSetting(saveDataBean, roomVipSetBean)) {
                viewModel.saveData(getActivity(), saveDataBean, functionRoomEnum.getServerApi());
                LogUtils.d("保存数据", saveDataBean);
                return false;
            }
        } else {
            //连续久坐
            VipFunSaveDataBean continuitySitBean = new VipFunSaveDataBean(
                    roomVipSetBean.getRoomUuid(),
                    roomVipSetBean.getRoomType(),
                    viewModel.functionSwitch.getValue() ? 1 : 0,
                    selectAlert,
                    0
            );
            //累计久坐
            VipFunSaveDataBean accumulateSitBean = new VipFunSaveDataBean(
                    roomVipSetBean.getRoomUuid(),
                    roomVipSetBean.getRoomType(),
                    viewModel.functionSwitch2.getValue() ? 1 : 0,
                    selectNotification,
                    0
            );
            if (isChangeSetting(continuitySitBean, roomVipSetBean)
                    || isChangeSetting(accumulateSitBean, accumulativeSetBean)) {
                viewModel.saveSedentaryData(getActivity(), continuitySitBean, accumulateSitBean);
                LogUtils.d("保存数据", continuitySitBean, accumulateSitBean);
                return false;
            }
        }
        return true;
    }

    private boolean isChangeSetting(VipFunSaveDataBean saveDataBean, RoomVipSetBean setBean){
        return setBean.getFunctionSwitch() != saveDataBean.getFunctionSwitch()
                || setBean.getFunctionAlert() != saveDataBean.getFunctionAlert()
                || setBean.getFunctionRemind() != saveDataBean.getFunctionRemind();
    }

    /** 初始化选择器数据 */
    private void initTimeMap(){
        alertSetting = functionRoomEnum.getAlertSetting();
        notificationSetting = functionRoomEnum.getNotificationSetting();

        if (null != alertSetting) {
            alertTimeMap = getTimeMap(alertSetting);
        }

        if (null != notificationSetting) {
            notificationTimeMap = getTimeMap(notificationSetting);
        }
    }

    private Map<String, Integer> getTimeMap(VipSettingTime vipSettingTime){
        int unitType = vipSettingTime.getUnitType();

        if (unitType == 0 || unitType == 1 || unitType == 3) {
            return getTimeList(
                    vipSettingTime.getStart(),
                    vipSettingTime.getEnd(),
                    vipSettingTime.getStep(),
                    unitType
            );
        } else if (unitType == 2){
            return getTimeListByClock(
                    vipSettingTime.getStart(),
                    vipSettingTime.getEnd(),
                    vipSettingTime.getStep(),
                    vipSettingTime.getDefaultValue()
            );
        } else {
            LogUtils.w("数据单位类型错误");
            return null;
        }
    }

    /** 检查报警与通知数据 */
    private boolean checkAlertAndNotifyData(){
        if (functionRoomEnum.getSettingType() == 3 && viewModel.functionSwitch.getValue()) {
            //校验数据
            boolean result = selectAlert > selectNotification;
            if (!result) {
                showErrorDialog();
            }
            return result;
        }

        return true;
    }

    /** 显示错误弹窗 */
    private void showErrorDialog(){
        if (null == errorDialog) {
            errorDialog = new CustomTitleTipsDialog(getContext());
            errorDialog.setTitle(getString(R.string.room_error_title));
            errorDialog.setTips(getString(R.string.room_error_alert_tips));
            errorDialog.setOnClickBottomListener(new CustomTitleTipsDialog.OnClickBottomListener() {
                @Override
                public void onPositiveClick() {
                    dismissErrorDialog();
                }

                @Override
                public void onNegtiveClick() {
                    dismissErrorDialog();
                }
            });
        }
        errorDialog.show();
    }

    /** 隐藏错误弹窗 */
    private void dismissErrorDialog(){
        if (null == errorDialog) {
            return;
        }
        errorDialog.dismiss();
    }

    /**
     * 显示选择器
     * @param timeMap   选择器数据
     * @param currentSettingItem    显示选中值的TextView
     * @param flag   选中的值存储
     * @param defaultIndex  默认选中值
     */
    private void showAlertPickerDialog(Map<String, Integer> timeMap, TextView currentSettingItem,
                                       int flag, int defaultIndex){
        pickerDialog = new BottomTextPickerDialog.Builder()
                .setType(Type.NUMBER)
                .setWheelItemTextSize(16)
                .setDefValue(defaultIndex)  //默认值（数组下标）
                .setThemeColor(getResources().getColor(R.color.app_colorAccent))
                .setIndexCallBack((timePickerView, selectIndex) -> {
                    selected(timeMap, selectIndex, currentSettingItem, flag);
                })
                .build(timeMap.keySet().toArray(new String[timeMap.size()]));
        pickerDialog.show(getChildFragmentManager(), BottomTextPickerDialog.class.getSimpleName());
    }

    private void dismissAlertPickerDialog(){
        if (null == pickerDialog) {
            return;
        }
        pickerDialog.dismiss();
    }

    private void selected(Map<String, Integer> timeMap, int selectIndex,
                          TextView currentSettingItem, int flag){
        if (!checkAlertAndNotifyData()) {
            return;
        }

        String[] array = timeMap.keySet().toArray(new String[timeMap.size()]);
        String key = array[selectIndex];
        currentSettingItem.setText(key);
        if (flag == FLAG_ALERT) {
            selectAlert = timeMap.get(key);
        } else {
            selectNotification = timeMap.get(key);
        }
    }

    /** 获取单位 */
    private String getUnit(int unitType){
        switch (unitType) {
            case 0:
                return " " + getString(R.string.room_minute);
            case 1:
                return " " + getString(R.string.room_hour);
            case 3:
                return " " + getString(R.string.room_count);
            default:
                return  "";
        }
    }

    private String getSettingValue(int unitType, int value, Map<String, Integer> timeList){
        String result = "";
        if (unitType == 1) {
            result = minuteToHour(value) + "";
        } else if (unitType == 2) {
            for (String s : timeList.keySet()) {
                int v = timeList.get(s);
                if (value == v) {
                    result = s;
                    return result;
                }
            }
            result = timeList.keySet().toArray(new String[timeList.size()])[0];
        }else {
            result = value + "";
        }

        return result + getUnit(unitType);
    }

    /** 获取默认值的数组下标索引 */
    private int getDefaultValueIndex(VipSettingTime vipSettingTime){
        if (null == vipSettingTime) {
            return 0;
        }
        return (vipSettingTime.getDefaultValue() - vipSettingTime.getStart()) / vipSettingTime.getStep();
    }

    /** 分钟转小时 */
    private float minuteToHour(float minute){
        return minute / 60;
    }

    /** 小时转分钟 */
    private int hourToMinute(float hour){
        return (int) (hour * 60);
    }

    /**
     * 生成选择时间（如果单位是小时，则自动转换成小时）
     * @param startTime
     * @param endTime
     * @param step
     * @param unitType
     * @return map（key是选择器中显示的，值为传输给服务器的数据）
     */
    public Map<String, Integer> getTimeList(int startTime, int endTime, int step, int unitType){
        Map<String, Integer> map = new LinkedHashMap<>();
        int i = startTime;
        do {
            String key;
            if (unitType == 1) {
                //转换成小时
                key = minuteToHour(i) + getUnit(unitType);
            } else {
                key = i + getUnit(unitType);
            }
            map.put(key, i);
        }while ((i += step) <= endTime);

        return map;
    }

    /**
     * 生成选择时间（时钟格式的数据，如：21:00、21:30）
     * @param startTime 开始的分钟
     * @param endTime  结束的分钟
     * @param step
     * @return
     */
    public static Map<String, Integer> getTimeListByClock(int startTime, int endTime, int step, int defaultValue){
        Map<String, Integer> map = new LinkedHashMap<>();
        for (int i = startTime; i <= endTime; i+= step) {
            int time = i;
            if (time >= 1440) {
                time -= 1440;
            }

            int hour = time / 60;
            int minute = time % 60;
            String timeStr = "";
            if (hour < 10) {
                timeStr += "0" + hour + ":";
            } else {
                timeStr += hour + ":";
            }

            if (minute < 10) {
                timeStr += "0" + minute;
            } else {
                timeStr += minute;
            }

            //第一个是选择器中显示的数据，第二个是数据索引
            map.put(timeStr, ((i - startTime) / step));
        }

        return map;
    }

    @Override
    public void onResume() {
        super.onResume();
        getBaseActivity().setTitle(functionRoomEnum.getName());
    }

    private RoomSettingFunctionActivity getBaseActivity(){
        FragmentActivity activity = getActivity();
        if (activity instanceof RoomSettingFunctionActivity) {
            return (RoomSettingFunctionActivity) activity;
        }

        return null;
    }

    @Override
    public void loadDataSuccess(BaseBean baseBean) {

    }

    @Override
    public void loadDataFail(String decs) {

    }

    @Override
    public void loginStatusChanged() {

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        dismissAlertPickerDialog();
    }
}
